/*
 * ccb_processor.c
 *
 *  Created on: 2014年11月30日
 *      Author: weiteng-jd
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ccb_connector.h"
#include "ccb_processor.h"

// 命令字
const uint32_t Cmd_SendClipboardData = 0x1000;
const uint32_t Cmd_RecvClipboardData = 0x1001;
const uint32_t Cmd_SendHeartbeat = 0x1002;
const uint32_t Cmd_RecvHeartbeatResult = 0x1003;

typedef struct ccb_client_info
{
	uint32_t dwGroupHashCode;
	int ifd;
} ccb_client_info;

ccb_client_info *g_cloud_clients[100];
uint32_t g_cloud_clients_count = 0;

char g_pro_szBuffer[1024 * 1024 * 5];

long long pro_getcurrtimeus()
{
	struct timeval stTime;
	gettimeofday(&stTime, NULL);
	long long tmpTime = stTime.tv_sec * 1000000ull;
	return tmpTime + stTime.tv_usec;
}

int pro_deserialize_pkg(char *pszBuffer, uint32_t dwRecvLength, uint32_t *pdwCmd, char **ppszBizPkg, uint32_t *pdwBizPkgLength)
{
	if (dwRecvLength < sizeof(uint32_t))
	{
		return -1;
	}
	else
	{
		memcpy(pdwCmd, pszBuffer, sizeof(uint32_t));

		uint32_t dwLength = dwRecvLength - sizeof(uint32_t);
		memcpy(pdwBizPkgLength, &dwLength, sizeof(uint32_t));

		*ppszBizPkg = (pszBuffer + sizeof(uint32_t));

		return 0;
	}
}

uint32_t pro_serialize_pkg(char **ppszBuffer, uint32_t dwCmd, char *pszBizPkg, uint32_t dwBizPkgLength)
{
	memset(g_pro_szBuffer, 0, sizeof(g_pro_szBuffer));
	// 返回地址
	*ppszBuffer = g_pro_szBuffer;

	// 序列化命令
	memcpy(g_pro_szBuffer, &dwCmd, sizeof(uint32_t));

	// 序列化数据
	if (pszBizPkg != NULL && dwBizPkgLength > 0)
	{
		memcpy(g_pro_szBuffer + sizeof(uint32_t), pszBizPkg, dwBizPkgLength);
		return dwBizPkgLength + sizeof(uint32_t);
	}
	else
	{
		return sizeof(uint32_t);
	}

}

void pro_update_clients(int ifd, uint32_t dwGroupHashCode)
{
	printf("client hash code:%u\n", dwGroupHashCode);
	// 刷新客户端
	int iIsFound = 0;
	int index = 0;
	for (; index < g_cloud_clients_count; index++)
	{
		if (g_cloud_clients[index]->ifd == ifd)
		{
			iIsFound = 1;
			break;
		}
	}

	if (iIsFound == 0)
	{
		g_cloud_clients[g_cloud_clients_count] = (ccb_client_info *) malloc(sizeof(ccb_client_info));
		g_cloud_clients[g_cloud_clients_count]->ifd = ifd;
		g_cloud_clients[g_cloud_clients_count]->dwGroupHashCode = dwGroupHashCode;
		g_cloud_clients_count++;
	}
}

void pro_send_clipboarddata(int ifd, uint32_t dwGroupHashcode, char *pszBizPkg, uint32_t dwBizPkgLength)
{
	char *pszData = NULL;
	uint32_t dwDataLength = pro_serialize_pkg(&pszData, Cmd_RecvClipboardData, pszBizPkg, dwBizPkgLength);

	int index = 0;
	for (; index < g_cloud_clients_count; index++)
	{
		int isDebug = 0;
		if (g_cloud_clients[index]->ifd != ifd || isDebug == 1)
		{
			conn_reset_and_senddata(g_cloud_clients[index]->ifd, pszData, dwDataLength);
		}
	}
}

void pro_cmd_recv_clipboarddata(int ifd, uint32_t dwGroupHashcode, char *pszBizPkg, uint32_t dwBizPkgLength)
{
	// 更新客户端列表
	pro_update_clients(ifd, dwGroupHashcode);

	// 发送给同组客户端
	pro_send_clipboarddata(ifd, dwGroupHashcode, pszBizPkg, dwBizPkgLength);
}

void pro_cmd_recv_heartbeat(int ifd, uint32_t dwGroupHashcode)
{
	// 更新客户端列表
	pro_update_clients(ifd, dwGroupHashcode);

	//回包
	char *pszData = NULL;
	uint32_t dwDataLength = pro_serialize_pkg(&pszData, Cmd_RecvHeartbeatResult, NULL, 0);
	conn_senddata(ifd, pszData, dwDataLength);
}

// 收到完整包
void pro_recv_pkg_data(int ifd, char *pszBuffer, uint32_t dwRecvLength)
{
	//memset(g_pro_szBuffer, 0, sizeof(g_pro_szBuffer));
	//memcpy(g_pro_szBuffer, pszBuffer, dwRecvLength);
	//pszBuffer = NULL;

	printf("ifd:%d, recv_pkg_data, length:%u\n", ifd, dwRecvLength);

	uint32_t dwCmd;
	char *pszBizPkg;
	uint32_t dwBizPkgLength;

	int iretcode = pro_deserialize_pkg(pszBuffer, dwRecvLength, &dwCmd, &pszBizPkg, &dwBizPkgLength);
	if (iretcode == 0)
	{
		printf("fd:%d, cmd:0x%x, dwBizPkgLength:%u\n", ifd, dwCmd, dwBizPkgLength);
		if (dwCmd == Cmd_SendClipboardData)
		{
			uint32_t clientHashcode = 0;
//			uint16_t istype = 0;
//			uint16_t iscompress = 0;
//			uint32_t datalength = 0;

			memcpy(&clientHashcode, pszBizPkg, sizeof(uint32_t));
//			memcpy(&istype, pszBizPkg + sizeof(uint32_t), sizeof(uint16_t));
//			memcpy(&iscompress, pszBizPkg + sizeof(uint32_t) + sizeof(uint16_t), sizeof(uint16_t));
//			memcpy(&datalength, pszBizPkg + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t), sizeof(uint32_t));
//
//			printf("clientHashcode:%u\n", clientHashcode);
//			printf("istype:%u\n", istype);
//			printf("iscompress:%u\n", iscompress);
//			printf("datalength:%u\n", datalength);
//
//			char data[datalength + 1];
//			memset(data, 0, datalength + 1);
//			memcpy(data, pszBizPkg + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t), datalength);
//
//			printf("data:%s\n", data);

			//收到剪贴板数据
			pro_cmd_recv_clipboarddata(ifd, clientHashcode, pszBizPkg, dwBizPkgLength);
		}
		else if (dwCmd == Cmd_SendHeartbeat)
		{
			uint32_t clientHashcode = 0;
			memcpy(&clientHashcode, pszBizPkg, sizeof(uint32_t));
			pro_cmd_recv_heartbeat(ifd, clientHashcode);

		}
	}
	else
	{
		printf("deserialize_pkg err.");
	}
}
